package cn.luoshaocheng.basic.service.impl;

import cn.luoshaocheng.basic.constant.RegisterConstant;
import cn.luoshaocheng.basic.exception.BusinessException;
import cn.luoshaocheng.basic.service.IVerifyCodeService;
import cn.luoshaocheng.basic.util.StrUtils;
import cn.luoshaocheng.basic.util.VerifyCodeUtils;
import cn.luoshaocheng.user.domain.User;
import cn.luoshaocheng.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public String getVerifyCode(String key) {
        //校验一波key值是否为空
        if(StringUtils.isEmpty(key)){
            throw  new BusinessException("参数有误！");
        }
        //生成随机验证码
        String code = StrUtils.getComplexRandomString(4);
        //存入redis中，设置过期时间
        redisTemplate.opsForValue().set(key,code,3, TimeUnit.MINUTES);

        //生成一个base64字符串 并返回到请前端
        return VerifyCodeUtils.verifyCode(80,40,code);


    }
    //注册操作

    @Override
    public void smsCode(Map<String, String> map) {
        String phone = map.get("phone");//电话号码
        String imageCode = map.get("imageCode");//图形验证码
        String imageCodeKey = map.get("imageCodeKey");//图形验证码对应得key
        // 1. 校验，参数不能为空
        if(StringUtils.isEmpty(phone)||
                StringUtils.isEmpty(imageCode) ||
                StringUtils.isEmpty(imageCodeKey)
        ){
            throw new BusinessException("参数不能为空");
        }
        // 2. 图形验证码校验
        Object obj = redisTemplate.opsForValue().get(imageCodeKey);
        if(obj==null){
            throw new BusinessException("图形验证码过期了，请重新获取输入！");
        }
        // 验证码不区分大小写
        if(!obj.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException("图形验证码输入错误！ 请重新输入！");
        }
        // 3. 手机号是否被注册过 查询user,
       User user= userMapper.findByPhone(phone);
        if(user!=null){
            throw new BusinessException("用户名已存在！请直接登录！");
        }
        /**
         * key: 手机号+业务键   业务键：最好是常量
         * value: code:时间戳
         * kty:value
         */
        // 4. 判断是否是第一次发送请求，或者是验证码过期  从redis中取
        Object value = redisTemplate.opsForValue().get(phone+RegisterConstant.PHONEREGISTER);
        String code=null;
        // 4.1. 如果取不到，没有发送过，获取过期了， 直接生成一个新的验证码保存到redis
        if(value==null){
            code = StrUtils.getComplexRandomString(6);
        }else{
            // 4.2. 如果取到了。判断是否超过一分钟。
           String redisTime = value.toString().split(":")[1];
            Long ltime = Long.valueOf(redisTime);
            // 4.2.1： 如果没超过1分钟，直接提示用户，1分钟之内不能多次发送。
            if(System.currentTimeMillis()-ltime<1*60*1000){
                throw new BusinessException("一分钟内不能发送多次！");
            }else{
                // 4.2.2： 如果超过了一分钟，刷新过期时间，
                code = value.toString().split(":")[0];
            }
        }

        // 4.2.2： 把code存入redisz中
        redisTemplate.opsForValue().set(phone+ RegisterConstant.PHONEREGISTER,
                code+":"+System.currentTimeMillis(),
                3,TimeUnit.MINUTES);

        // 5. 发送短信给用户
        System.out.println("您的验证码为："+code+",请在三分钟之内使用");
        // SmsSendUtil.sendSms(phone,"您的验证码为："+code+",请在三分钟之内使用");
    }

    @Override
    public void binderSmsCode(Map<String, String> map) {
        String phone = map.get("phone");//电话号码

        // 1. 校验，参数不能为空
        if(StringUtils.isEmpty(phone)
        ){
            throw new BusinessException("手机号不能为空");
        }
        // 2. 图形验证码校验


        /**
         * key: 手机号+业务键   业务键：最好是常量
         * value: code:时间戳
         * kty:value
         */
        // 4. 判断是否是第一次发送请求，或者是验证码过期  从redis中取
        Object value = redisTemplate.opsForValue().get(phone+RegisterConstant.WXBINDER);
        String code=null;
        // 4.1. 如果取不到，没有发送过，获取过期了， 直接生成一个新的验证码保存到redis
        if(value==null){
            code = StrUtils.getComplexRandomString(6);
        }else{
            // 4.2. 如果取到了。判断是否超过一分钟。
            String redisTime = value.toString().split(":")[1];
            Long ltime = Long.valueOf(redisTime);
            // 4.2.1： 如果没超过1分钟，直接提示用户，1分钟之内不能多次发送。
            if(System.currentTimeMillis()-ltime<1*60*1000){
                throw new BusinessException("一分钟内不能发送多次！");
            }else{
                // 4.2.2： 如果超过了一分钟，刷新过期时间，
                code = value.toString().split(":")[0];
            }
        }

        // 4.2.2： 把code存入redisz中
        redisTemplate.opsForValue().set(phone+ RegisterConstant.WXBINDER,
                code+":"+System.currentTimeMillis(),
                3,TimeUnit.MINUTES);

        // 5. 发送短信给用户
        System.out.println("您的验证码为："+code+",请在三分钟之内使用");
        // SmsSendUtil.sendSms(phone,"您的验证码为："+code+",请在三分钟之内使用");
    }
}
